<?php
/**************************************************************************
 *
 *   Copyright 2010 American Public Media Group
 *
 *   This file is part of AIR2.
 *
 *   AIR2 is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   AIR2 is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with AIR2.  If not, see <http://www.gnu.org/licenses/>.
 *
 *************************************************************************/

/**
 * Inquiry
 *
 * A collection of questions sent out to sources
 *
 * @property integer $inq_id
 * @property string $inq_uuid
 * @property string $inq_title
 * @property string $inq_ext_title
 * @property timestamp $inq_publish_dtim
 * @property string $inq_desc
 * @property string $inq_type
 * @property integer $inq_xid
 * @property integer $inq_loc_id
 * @property boolean $inq_public_flag
 * @property string $inq_status
 * @property string $inq_expire_msg
 * @property timestamp $inq_expire_dtim
 * @property integer $inq_cre_user
 * @property integer $inq_upd_user
 * @property timestamp $inq_cre_dtim
 * @property timestamp $inq_upd_dtim
 * @property Doctrine_Collection $ProjectInquiry
 * @property Doctrine_Collection $Question
 * @property Doctrine_Collection $SrcResponseSet
 * @property Doctrine_Collection $SrcInquiry
 * @author rcavis
 * @package default
 */
class Inquiry extends AIR2_Record {
    /* code_master values */
    public static $STATUS_ACTIVE = 'A';
    public static $STATUS_INACTIVE = 'F';
    public static $TYPE_FORMBUILDER = 'F';

    /**
     * Set the table columns
     */
    public function setTableDefinition() {
        $this->setTableName('inquiry');
        $this->hasColumn('inq_id', 'integer', 4, array(
                'primary' => true,
                'autoincrement' => true,
            ));
        $this->hasColumn('inq_uuid', 'string', 12, array(
                'fixed' => true,
                'notnull' => true,
                'unique' => true,
            ));
        $this->hasColumn('inq_title', 'string', 128, array(
                'notnull' => true,
            ));
        $this->hasColumn('inq_ext_title', 'string', 256, array(

            ));
        $this->hasColumn('inq_publish_dtim', 'timestamp', null, array(

            ));
        $this->hasColumn('inq_deadline_dtim', 'timestamp', null, array(

            ));
        $this->hasColumn('inq_desc', 'string', 255, array(

            ));
        $this->hasColumn('inq_type', 'string', 1, array(
                'fixed' => true,
                'notnull' => true,
                'default' => self::$TYPE_FORMBUILDER,
            ));
        $this->hasColumn('inq_xid', 'integer', 4, array(

            ));
        $this->hasColumn('inq_loc_id', 'integer', 4, array(
                'default' => 52, /* en_US -- see Locale.yml */
                'notnull' => true,
            ));
        $this->hasColumn('inq_public_flag', 'boolean', null, array(
                'notnull' => true,
            ));
        $this->hasColumn('inq_status', 'string', 1, array(
                'fixed' => true,
                'notnull' => true,
                'default' => self::$STATUS_ACTIVE,
            ));
        $this->hasColumn('inq_expire_msg', 'string', null, array(

            ));
        $this->hasColumn('inq_expire_dtim', 'timestamp', null, array(

            ));
        $this->hasColumn('inq_cre_user', 'integer', 4, array(
                'notnull' => true,
            ));
        $this->hasColumn('inq_upd_user', 'integer', 4, array(

            ));
        $this->hasColumn('inq_cre_dtim', 'timestamp', null, array(
                'notnull' => true,
            ));
        $this->hasColumn('inq_upd_dtim', 'timestamp', null, array(

            ));

        parent::setTableDefinition();
    }


    /**
     * Set table relations
     */
    public function setUp() {
        parent::setUp();
        $this->hasMany('ProjectInquiry', array(
                'local' => 'inq_id',
                'foreign' => 'pinq_inq_id'
            ));
        $this->hasMany('Question', array(
                'local' => 'inq_id',
                'foreign' => 'ques_inq_id'
            ));
        $this->hasMany('SrcResponseSet', array(
                'local' => 'inq_id',
                'foreign' => 'srs_inq_id'
            ));
        $this->hasMany('SrcInquiry', array(
                'local' => 'inq_id',
                'foreign' => 'si_inq_id'
            ));
        $this->hasOne('Locale', array(
                'local' => 'inq_loc_id',
                'foreign' => 'loc_id'
            ));

        // Tagging
        $this->hasMany('TagInquiry as Tags', array(
                'local' => 'inq_id',
                'foreign' => 'tag_xid'
            ));
    }


    /**
     *
     *
     * @param array   $prjs
     */
    public function add_projects(array $prjs) {
        foreach ($prjs as $prj) {
            $pinq = new ProjectInquiry;
            $pinq->pinq_prj_id = $prj->prj_id;
            $pinq->pinq_status = 'A';
            $this->ProjectInquiry[] = $pinq;
        }
    }


    /**
     *
     *
     * @param User    $user
     * @return authz integer
     */
    public function user_may_read($user) {
        if ($user->is_system()) {
            return AIR2_AUTHZ_IS_SYSTEM;
        }       

        foreach ($this->ProjectInquiry as $pinq) {
            $ret = $pinq->Project->user_may_read($user);
            if ($ret) {
                return $ret;
            }
        }
        return AIR2_AUTHZ_IS_DENIED;
    }



    /**
     *
     *
     * @param User    $user
     * @return authz integer
     */
    public function user_may_write($user) {
        if ($user->is_system()) {
            return AIR2_AUTHZ_IS_SYSTEM;
        }       

        foreach ($this->ProjectInquiry as $pinq) {
            $ret = $pinq->Project->user_may_write($user);
            if ($ret) {
                return $ret;
            }
        }
        return AIR2_AUTHZ_IS_DENIED;
    }



    /**
     *
     *
     * @param User    $user
     * @return authz integer
     */
    public function user_may_manage($user) {
        if ($user->is_system()) {
            return AIR2_AUTHZ_IS_SYSTEM;
        }       

        foreach ($this->ProjectInquiry as $pinq) {
            $ret = $pinq->Project->user_may_manage($user);
            if ($ret) {
                return $ret;
            }
        }
        return AIR2_AUTHZ_IS_DENIED;
    }


    /**
     * Apply authz rules for who may view the existence of an Inquiry.
     *
     * @param AIR2_Query $q     (reference)
     * @param User    $u     (reference)
     * @param string  $alias (optional)
     */
    public static function query_may_read(AIR2_Query &$q, User &$u, $alias=null) {
        if ($u->is_system()) {
            return;
        }
        //Carper::carp("Inquiry::query_may_read: " . $q->getSqlQuery() . " alias=$alias");
        $a = ($alias) ? "$alias." : "";
        $user_id = $u->user_id;

        // if any of the Projects are readable, then the Inquiry is readable
        $shared_orgs = "${a}inq_id IN " .
            "(SELECT pinq1.pinq_inq_id FROM ProjectInquiry pinq1 WHERE pinq1.pinq_status = 'A' AND pinq1.pinq_prj_id IN " .
            " (SELECT po1.porg_prj_id FROM ProjectOrg po1 WHERE po1.porg_status = 'A' AND po1.porg_org_id IN " .
            "  (SELECT uo1.uo_org_id FROM UserOrg uo1 WHERE uo1.uo_status = 'A' AND uo1.uo_user_id = $user_id)" .
            " )" .
            ")";
        $q->addWhere($shared_orgs);

        $project_is_shared = "${a}inq_id IN " .
            "(SELECT pinq2.pinq_inq_id FROM ProjectInquiry pinq2 WHERE pinq2.pinq_status = 'A' AND pinq2.pinq_prj_id IN " .
            " (SELECT prj2.prj_id FROM Project prj2 WHERE prj2.prj_shared_flag = 1)" .
            ")";
        $q->orWhere($project_is_shared);

        //diag($q->getSqlQuery());

    }


    /**
     * Apply authz rules for who may write to an Inquiry.
     *
     * @param AIR2_Query $q     (reference)
     * @param User    $u     (reference)
     * @param string  $alias (optional)
     */
    public static function query_may_write(AIR2_Query &$q, User &$u, $alias=null) {
        if ($u->is_system()) {
            return;
        }
        $a = ($alias) ? "$alias." : "";
        $user_id = $u->user_id;

        // TODO would there ever be a case where the owner was not a WRITER in a related org?
        // not if user_may_write() is always used before save().
        $org_str = $u->get_authz_str(AIR2_AUTHZ_WRITER, 'po2.porg_org_id');

        // user is an owner (manager) of project
        $is_owner = "${a}inq_id IN " .
            "(SELECT pinq3.pinq_inq_id FROM ProjectInquiry pinq3 WHERE pinq3.pinq_status = ? AND pinq3.pinq_prj_id IN " .
            " (SELECT po1.porg_prj_id FROM ProjectOrg po1 WHERE po1.porg_status = ? AND po1.porg_contact_user_id = ?)" .
            ")";
        $q->addWhere($is_owner, array(ProjectInquiry::$STATUS_ACTIVE, ProjectOrg::$STATUS_ACTIVE, $user_id));

        // or user is a WRITER in a related org
        $has_writer_role = "${a}inq_id IN " .
            "(SELECT pinq4.pinq_inq_id FROM ProjectInquiry pinq4 WHERE pinq4.pinq_status = ? AND pinq4.pinq_prj_id IN " .
            " (SELECT po2.porg_prj_id FROM ProjectOrg po2 WHERE po2.porg_status = ? AND $org_str)" .
            ")";
        $q->orWhere($has_writer_role, array(ProjectInquiry::$STATUS_ACTIVE, ProjectOrg::$STATUS_ACTIVE));

        //diag($q->getSqlQuery());

    }


    /**
     * Apply authz rules for who may manage an Inquiry.
     *
     * @param AIR2_Query $q     (reference)
     * @param User    $u     (reference)
     * @param string  $alias (optional)
     */
    public static function query_may_manage(AIR2_Query &$q, User &$u, $alias=null) {
        if ($u->is_system()) {
            return;
        }
        $a = ($alias) ? "$alias." : "";
        $user_id = $u->user_id;

        // user is an owner (manager) of project
        $is_owner = "${a}inq_id IN " .
            "(SELECT pinq5.pinq_inq_id FROM ProjectInquiry pinq5 WHERE pinq5.pinq_prj_id IN " .
            " (SELECT po1.porg_prj_id FROM ProjectOrg po1 WHERE po1.porg_contact_user_id = ?)" .
            ")";
        $q->addWhere($is_owner, $user_id);

        //diag($q->getSqlQuery());
    }


}
